import os
import re
import time
import numpy as np
from fnmatch import fnmatchcase

def get_time():
    return time.strftime("%H:%M:%S", time.localtime())

def create_dir_not_exist(path):
    if not os.path.exists(path):
        os.mkdir(path)
    else:
        print(path+' is exist')
    return 0

def read_num(a):
    b=''
    break_label=0
    for i in range(len(a)):
        if a[i].isdigit():
            b=b+a[i]
            break_label=1
        if a[i].isdigit() is False and break_label==1:
            break
    return b

def rename(path):
    files = os.listdir(path)
    for file in files:
        file_path = os.path.join(path, file)
        if fnmatchcase(file,'N??.data') is False and os.path.isfile(file_path):
            n = file.find('N')
            name = 'N' + read_num(file[n:len(file)]) + '.data'
            new_name = os.path.join(path, name)
            if not os.path.exists(new_name):
                os.rename(file_path, new_name)
            else:
                print(new_name + ' is exists')
    return 0

def readname(name):
    name=name.replace('.data','')
    key=re.findall('[a-zA-Z]+', name)
    value=[0 for i in range(len(key))]
    tmp=name.split('_')
    condi={}
    for i in range(len(tmp)):
        try:
            if 'inf' in key[i]:
                key[i]=key[i].replace('inf','')
        except:
            print(tmp,i)
        value[i]=tmp[i].replace(key[i],'')
    for i in range(len(key)):
        condi[key[i]]=value[i]
    return condi

def readmodel(name):
    with open(name,'r') as f:
        lines=f.readlines()
    atom_num=int(lines[2].split()[0])
    bond_num=int(lines[3].split()[0])

def read_modellist(path):
    files = os.listdir(path)
    model_list = []
    for file in files:
        file_path = os.path.join(path, file)
        if os.path.isfile(file_path):
            n = file.find('N')
            model_list.append(int(read_num(file[n + 1:len(file)])))
    return model_list


def changecode(filename, key, value):
    """
    修改指定文件中的某一行内容，根据关键字定位行并执行不同的操作。

    使用方法：
        1. 函数会打开指定的文件并逐行搜索包含 `key` 的行（只处理首次匹配）。
        2. 根据 `value` 参数指定的操作类型，执行以下功能：
            - "note"：将找到的行注释掉（在行首添加 `#`），如果已注释则不做处理。
            - "denote"：移除找到的行的注释（删除行首的 `#`），如果未注释则不做处理。
            - 其他值：对找到行进行以下处理：
                a) 如果在主内容部分匹配到 `key = [……]`（即 `key` 位于一对中括号 `[]` 中），
                   则将整个中括号连同其中的内容替换为新的 `value`，即变为 `[value]`。
                b) 如果 `key` 不在 `[]` 中，则仅修改该行主内容的最后一个字段为 `value`，
                   同时保留原有的注释内容（若有）。

    参数说明：
        filename (str): 要修改的文件名或路径。
        key (str): 用于定位行的关键字。
        value (str): 指定的操作类型或新值：
            - "note"：注释目标行。
            - "denote"：取消注释目标行。
            - 其他值：
                1) 若找到行中 `key = [某内容]` 则替换方括号及其中内容为 `[value]`。
                2) 若 `key` 不出现在方括号中，则修改该行主内容的最后一个字段为 `value`。

    返回值：
        int:
            - 1：成功修改。
            - 0：未找到关键字或操作失败。

    示例：
        假设文件内容为：
            line 1: a = [5]  # variable a
            line 2: b = 10   # variable b
        
        示例 1: 注释掉包含 "a" 的行
            changecode('example.txt', 'a', 'note')
            # 修改后文件内容：
            #   line 1: # a = [5]  # variable a
            #   line 2: b = 10   # variable b

        示例 2: 取消注释包含 "a" 的行
            changecode('example.txt', 'a', 'denote')
            # 修改后文件内容：
            #   line 1: a = [5]  # variable a
            #   line 2: b = 10   # variable b

        示例 3: 若 `key` 不在 `[ ]` 中，则修改主内容最后一个字段
            changecode('example.txt', 'b', '20')
            # 修改后文件内容：
            #   line 1: a = [5]  # variable a
            #   line 2: b = 20   # variable b

        示例 4: 若 `key` 出现在 `[]` 中则替换整个括号及其中内容
            changecode('example.txt', 'a', '100')
            # 修改后文件内容：
            #   line 1: a = [100]  # variable a
            #   line 2: b = 10     # variable b
    """

    value = str(value)
    with open(filename, 'r', encoding='utf8') as f:
        code = f.readlines()

    line_index = -1  # 用于记录匹配行的索引

    # 1. 找到包含 key 的行
    for i in range(len(code)):
        if key in code[i]:  # 简单判断是否包含 key
            line_index = i
            break

    if line_index == -1:
        print('没有找到关键字')
        return 0

    # 2. 根据 value 的类型进行不同处理
    line_content = code[line_index].rstrip('\n')  # 去除行末换行符

    # ---------- 2.1 处理 "note" ----------
    if value == 'note':
        # 如果行首还没有被注释，则在行首插入 "# "
        if not line_content.lstrip().startswith('#'):
            code[line_index] = '# ' + line_content + '\n'
        # 如果已经被注释则不做任何处理

    # ---------- 2.2 处理 "denote" ----------
    elif value == 'denote':
        stripped_line = line_content.lstrip()
        if stripped_line.startswith('#'):
            # 计算 # 之前的空格数量
            leading_spaces = len(line_content) - len(stripped_line)
            # 移除第一个 '#' 以及紧随其后的一个空格（若存在）
            if len(stripped_line) > 1 and stripped_line[1] == ' ':
                new_content = ' ' * leading_spaces + stripped_line[2:]
            else:
                new_content = ' ' * leading_spaces + stripped_line[1:]
            code[line_index] = new_content + '\n'
        # 如果没有注释则不做处理

    # ---------- 2.3 处理其他值 ----------
    else:
        # 拆分为主内容和注释部分，主内容在 '#' 之前，注释在 '#' 之后
        if '#' in line_content:
            comment_start = line_content.index('#')
            main_part = line_content[:comment_start].rstrip()
            comment_part = line_content[comment_start:].rstrip()
        else:
            main_part = line_content
            comment_part = ""

        # 如果主内容存在形如 "...[key]..." 的结构，则替换方括号内容为新值
        # 先构造一个匹配 key = [任何字符] 的正则表达式（不区分空格）
        # \bkey\b 代表匹配独立的单词"key"，再加上可选空格、=、可选空格、\[.*?\]
        # 简化处理：若要匹配更多复杂情况，可根据具体需求增强正则
        
        pattern = rf'.*\[{re.escape(key)}\].*'
        match = re.search(pattern, line_content)

        if match:
            # 将 [……] 整体替换为 [value]
            # 注意只替换匹配到的中括号内容，不改变其他部分
            new_main_part = re.sub(r"\[.*?\]", f"{value}", main_part)
            new_line = new_main_part
        else:
            # 如果没有匹配到 key = [xxx]，则修改该行主内容的最后一个字段
            main_parts = main_part.split()
            if not main_parts:
                # 如果行内容空，则不做操作
                return 0
            # 修改最后一个字段为 value
            main_parts[-1] = value
            new_line = ' '.join(main_parts)

        # 组合新行和注释
        if comment_part:
            new_line = f"{new_line} {comment_part}"

        code[line_index] = new_line + '\n'

    # 3. 写回修改后的文件
    with open(filename, 'w', encoding='utf8') as f:
        f.writelines(code)

    return 1  # 表示成功



def note_line(filename, key, killFlag=True):
    # 打开文件读取内容
    with open(filename, 'r', encoding='utf8') as f:
        code = f.readlines()
    
    for i in range(len(code)):
        # 分割行内容和注释部分
        line_content = code[i].split('#', 1)  # 按#分割，最多分割1次
        main_part = line_content[0].strip()  # 主内容去掉前后空格
        comment_part = f" #{line_content[1]}" if len(line_content) > 1 else ""  # 保留注释部分

        # 检查关键字列表中的元素是否存在于主内容中
        if any(k in main_part for k in key):
            # 如果 killFlag 为 True，则注释掉这一行
            if killFlag:
                if not main_part.startswith('#'):  # 避免重复注释
                    code[i] = f"# {main_part}{comment_part}\n"
            # 如果 killFlag 为 False，则取消注释这一行
            else:
                if main_part.startswith('#'):  # 去掉注释
                    code[i] = main_part.lstrip('#').strip() + comment_part + '\n'

    # 写回修改后的文件
    with open(filename, 'w', encoding='utf8') as f:
        f.writelines(code)

    return

def readmap(filename):
    with open(filename, 'r') as f:
        lines = f.readlines()
    map = []
    bondlist=[]
    n=1
    for line in lines:
        if 'bondlist' in line:
            n=0
            continue
        tmp=line.strip().split(';')
        for i in range(len(tmp)):
            if '[' in tmp[i]:
                tmp[i]=tmp[i][1:-1].split(', ')
                if len(tmp[i][0])==0:
                    tmp[i]=[]
                    continue
                for j in range(len(tmp[i])):
                    tmp[i][j]=int(tmp[i][j])
            else:
                tmp[i]=int(tmp[i])
        if n:
            map.append(chain(tmp[0],tmp[1],tmp[2],tmp[3],tmp[4]))
        else:
            bondlist.append(bond(tmp[0],tmp[1][0],tmp[1][1]))
    return map,bondlist

def read_dir(path):
    files = os.listdir(path)
    return files

def column(a,b):
    c = []
    for i in range(len(a)):
        c.append(a[i][b])
    return c

def mean_and_std_err(irregular_list):
    mean_values = []
    std_err_values = []

    for sublist in irregular_list:
        if sublist:  # 非空列表
            array = np.array(sublist)
            mean = np.mean(array)
            std_err = np.std(array) / np.sqrt(len(array))
            mean_values.append(mean)
            std_err_values.append(std_err)
        else:  # 空列表
            mean_values.append(None)
            std_err_values.append(None)

    return mean_values, std_err_values

class atom:
    def __init__(self, id, loca, type):
        self.id = id
        self.loca = loca
        self.molecule = 1
        self.type = type
        self.mass = 1
        self.count = 0  # 标记遍历的次数，不能超过一次
        self.unit=None
        self.PB_cross_flag=None
        self.connect = []

class bond:
    def __init__(self, Id, End1, End2):
        self.id = Id
        self.type = 1
        self.end = [End1,End2]

class crosslink:
    def __init__(self, id, loca):
        self.id = id
        self.loca = loca
        self.neighbor = []
        self.real_id = -1

class cell:
    def __init__(self, cellnum):
        self.position = cellnum
        self.crosslink = []

class chain:
    def __init__(self,id=-1,length=0,crosslink=[],atomlist=[],bondlist=[]):
        self.id = id
        self.crosslink=crosslink
        self.atomlist = atomlist
        self.bondlist = bondlist
        self.len=length

class trace:
    def __init__(self,trace):
        self.id = 0
        self.trace = trace
        self.time = 0
    
        
if __name__ == '__main__':
    a=readname('k1_gamma0.1')
    print(a)